#pragma once

#include <optional>
#include "protocol/transport.pb.h"

namespace zeroplus::mq
{
   // ---------------------- 服务端处理器基类 ----------------------
    class RequestHandler
    {
    public:
        virtual ~RequestHandler() = default;
        virtual std::optional<transport::ReplyCommand> Handle(const Bytes &request) = 0;
    };

    // ---------------------- 服务端模板处理器 ----------------------
    template <typename Req, typename Resp>
    class TemplateRequestHandler : public RequestHandler
    {
    public:
        using HandlerFunc = std::function<Resp(const Req &)>;

    private:
        HandlerFunc handler_;

    public:
        TemplateRequestHandler(HandlerFunc handler)
            : handler_(std::move(handler))
        {
        }

        std::optional<transport::ReplyCommand> Handle(const Bytes &requestBytes) override
        {
            auto request = ProtocolCodec<Req>::Decode(requestBytes);
            if constexpr (std::is_void<Resp>::value)
            {
                handler_(request);
                return std::nullopt;
            }
            else
            {
                auto response = handler_(request);
                transport::ReplyCommand reply;
                reply.set_code(response.code());
                reply.set_body(ProtocolCodec<Resp>::Encode(response).to_string());
                return std::make_optional(reply);
            }
        }
    };

}